package com.mspbots.rule.exceptions.cw;

import cn.hutool.core.util.StrUtil;
import com.mspbots.cw.request.MessagesDTO;
import com.mspbots.cw.request.TenantTimeEntryDTO;
import lombok.extern.slf4j.Slf4j;
import org.jeasy.rules.annotation.Action;
import org.jeasy.rules.annotation.Condition;
import org.jeasy.rules.annotation.Fact;
import org.jeasy.rules.annotation.Rule;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * com.mspbots.rule.exceptions.timeentry.Overlapped
 *
 * @author Jun Zhou
 * @description
 * @date 12:43 2019/6/14
 **/
@Slf4j
@Rule(name = "Overlapped", description = "Employee logged an overlapped time log.")
public class Overlapped extends CwBaseRule implements IcwBaseRule {

    private TenantTimeEntryDTO overlappedEntry;

    @Condition
    @Override
    public boolean condition(@Fact(FACT) TenantTimeEntryDTO entry) {
        try {
            if (!setUserMapping(entry.getTenantUserId()) || super.checkMessage(entry)) {
                return false;
            }


            Map<String, Object> params = new HashMap<>(16);
            params.put("tenantId", tenantRuleDTO.getTenantId());
            params.put("tenantUserId", entry.getTenantUserId());
            params.put("enteredDateStart", LocalDateTime.of(LocalDate.now(), LocalTime.MIN));

            List<TenantTimeEntryDTO> userTimeEntryList = tenantUserTimeEntryService.listByTenantUserId(params);

            if (CollectionUtils.isEmpty(userTimeEntryList)) {
                return false;
            }


            for (TenantTimeEntryDTO tenUserTimeEntry : userTimeEntryList) {
                if (tenUserTimeEntry.getCwTid().equals(entry.getCwTid())
                        || ignoreSeconds(entry.getBeginDate()).isAfter(ignoreSeconds(tenUserTimeEntry.getEndDate()))
                        || ignoreSeconds(entry.getBeginDate()).equals(ignoreSeconds(tenUserTimeEntry.getEndDate()))
                        || ignoreSeconds(entry.getEndDate()).isBefore(ignoreSeconds(tenUserTimeEntry.getBeginDate()))
                        || ignoreSeconds(entry.getEndDate()).equals(ignoreSeconds(tenUserTimeEntry.getBeginDate()))) {
                    continue;
                } else {
                    this.overlappedEntry = tenUserTimeEntry;

                    // check if already insert message for this entry
                    MessagesDTO checkMessageDto = new MessagesDTO();
                    checkMessageDto.setTimeEntryId(tenUserTimeEntry.getCwTid());
                    if (super.checkMessage(checkMessageDto)) {
                        return false;
                    }
                    return true;
                }
            }
        } catch (Exception e) {
            log.error("Overlapped : {}", entry);
        }

        return false;
    }

    private LocalDateTime ignoreSeconds(LocalDateTime dateTime) {
        return LocalDateTime.of(dateTime.toLocalDate(), LocalTime.of(dateTime.getHour(), dateTime.getMinute(), 0));

    }

    /**
     * @param entry
     * @return void
     * @author Jun Zhou
     * @description
     * @date 12:25 2019/6/14
     **/
    @Action
    @Override
    public void action(@Fact(FACT) TenantTimeEntryDTO entry) {
        String msg = buildMessage(entry.getEnteredDate());
        Map<String, Object> params = new HashMap<>();
        params.put("TimeEntryLink1", suffixCwLink(entry.getCwTid()));
        params.put("TimeEntryLink2", suffixCwLink(overlappedEntry.getCwTid()));
        params.put("StartTime1", styleParam(formatZoneTime(entry.getBeginDate()).toString()));
        params.put("EndTime1", styleParam(formatZoneTime(entry.getEndDate()).toString()));
        params.put("StartTime2", styleParam(formatZoneTime(overlappedEntry.getBeginDate()).toString()));
        params.put("EndTime2", styleParam(formatZoneTime(overlappedEntry.getEndDate()).toString()));
        String message = StrUtil.format(msg, params);
        messages.setMessage(message);
        messages.setBusinessId(entry.getCwTid());
        insertMessage();
    }


}
